package com.qingyun.customview.bezier.path_anim

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PathMeasure
import android.graphics.Point
import android.graphics.PointF
import android.graphics.PorterDuff
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.ImageView
import android.widget.RelativeLayout
import androidx.annotation.ColorInt
import androidx.core.animation.addListener
import com.qingyun.customview.R
import kotlin.random.Random
import androidx.core.graphics.createBitmap

class StarViewGroup @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : RelativeLayout(context, attrs, defStyleAttr), View.OnClickListener {

    private val mColorPool = listOf(
        Color.RED,
        Color.GREEN,
        Color.BLUE,
        Color.YELLOW,
        Color.MAGENTA,
        Color.CYAN,
    )
    private val mPaint: Paint = Paint().apply {
        color = Color.BLACK
        style = Paint.Style.STROKE
        strokeWidth = 5f
    }
    private val mPath: Path = Path()
    private val originalBitmap = BitmapFactory.decodeResource(resources, R.drawable.ic_starts2)

    private var mScreenWidth: Int = resources.displayMetrics.widthPixels
    private var mScreenHeight: Int = resources.displayMetrics.heightPixels
    private var mStartPoint: PointF = PointF()
    private var mEndPoint: PointF = PointF()
    private var mCon1Point: PointF = PointF()
    private var mCon2Point: PointF = PointF()

    init {
        setOnClickListener(this)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mScreenWidth = w
        mScreenHeight = h
        mStartPoint = PointF(mScreenWidth * 1.0f / 2, mScreenHeight * 1.0f)
        mEndPoint = PointF(mScreenWidth * 1.0f / 2, 0f)
        mCon1Point = PointF(mScreenWidth * 1.0f, mScreenHeight * 1.0f * 3 / 4)
        mCon2Point = PointF(0f, mScreenHeight * 1.0f / 4)
    }

    private fun createStar(@ColorInt color: Int): Bitmap {
        val outBitmap = createBitmap(
            originalBitmap.width,
            originalBitmap.height,
            originalBitmap.config
        )
        val canvas = Canvas(outBitmap)
        canvas.drawBitmap(originalBitmap, 0f, 0f, mPaint)
        canvas.drawColor(color, PorterDuff.Mode.SRC_IN)
        canvas.setBitmap(null)
        return outBitmap
    }

    private fun addStar() {
        val starColor = mColorPool[Random.nextInt(mColorPool.size)]
        val starBitmap = createStar(starColor)

        val lp = LayoutParams(starBitmap.width, starBitmap.height).apply {
            addRule(ALIGN_PARENT_BOTTOM)
            addRule(CENTER_HORIZONTAL)
        }
        val starView = ImageView(context).apply {
            setImageBitmap(starBitmap)
        }
        addView(starView, lp)


        mPath.reset()
        mPath.moveTo(mStartPoint.x, mStartPoint.y)
        mPath.cubicTo(
            mCon1Point.x,
            mCon1Point.y,
            mCon2Point.x,
            mCon2Point.y,
            mEndPoint.x,
            mEndPoint.y
        )
        val pathMeasure = PathMeasure(mPath, false)
        val moveAnimator = ValueAnimator.ofFloat(0f, pathMeasure.length).apply {
            interpolator = LinearInterpolator()
            addUpdateListener {
                val value = it.animatedValue as Float
                val pos = FloatArray(2)
                pathMeasure.getPosTan(value, pos, null)
                starView.x = pos[0]
                starView.y = pos[1]
            }
        }
        val alphaAnimator = ObjectAnimator.ofFloat(starView, "alpha", 1.0f, 0f)
        val animatorSet = AnimatorSet().apply {
            duration = 4000
            addListener(
                onEnd = {
                    removeView(starView)
                }
            )
        }
        animatorSet.play(moveAnimator).with(alphaAnimator)
        animatorSet.start()
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
    }

    override fun onClick(v: View?) {
        //addStar()
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        mStartPoint = PointF(mScreenWidth.toFloat() / 2, mScreenHeight.toFloat())
        mEndPoint = PointF(mScreenWidth.toFloat() / 2 + 150 * Random.nextFloat(), 0f)
        mCon1Point = PointF(
            mScreenWidth * Random.nextFloat(),
            mScreenHeight.toFloat() * 3 * Random.nextFloat() / 4
        )
        mCon2Point = PointF(
            0f,
            mScreenHeight.toFloat() * Random.nextFloat() / 4
        )
        addStar()
        return true
    }
}